package com.vinjogames.gfx;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLU;

import com.vinjogames.TankGame.TankGameActivity;
import com.vinjogames.entities.Game;
import com.vinjogames.ui.TitleMenu;
import com.vinjogames.util.GameClock;
import com.vinjogames.util.Logger;
import com.vinjogames.util.SoundManager;


public class GameRenderer implements GameView.Renderer{

	private TankGameActivity mActivity;
	private Game mGame;
	private GameClock mClock;
	private Camera mCamera;
	private TitleMenu mMenu;

	private static long mLastTime;
	private int mLoadGameResources;

	public GameRenderer(TankGameActivity activity)
	{
		mActivity = activity;
		mGame     = activity.getGame();
		mMenu     = activity.getMenu();
		mClock    = GameClock.getInstance();
		mCamera   = Camera.getInstance();
		mLastTime = 0;
		mLoadGameResources = -1;
	}

	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		//Load textures here, everytime this is run
		//it means that open gl context has been destroyed
		//i.e... all textures are gone, and need to be reloaded
		//so everytime onPause/onResume
	
		boolean supportsDrawTexture = gl.glGetString(GL10.GL_EXTENSIONS).contains("draw_texture");
		int[] maxTextureSize = new int[1];
		gl.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSize, 0);
		Logger.log("[GameRenderer]: Supports draw texture: " + supportsDrawTexture);
		Logger.log("[GameRenderer]: Max Texture Size: " + maxTextureSize[0]);
		
		//Load all resources here!
		//Maybe move this somewhere else
		//Makes it easier to load all assets at once like at a loading screen.
		//Or load images at loading screen, and load them into texture buffers here?
		SpriteSheet.getInstance().loadUITextures(gl);
		
		mMenu.load();//This needs to be after spritesheet.loadalltextures
		Font.load(gl);//This needs to be after spritesheet.loadalltextures
		
//		SpriteSheet.getInstance().loadAllTextures(gl);  //This can only be here
//		AnimationSheet.getInstance().loadAllTextures(gl);
//		SoundManager.getInstance().LoadResources(mActivity);//This can be moved anywhere
//		AnimationManager.getInstance().initializeManager();
//		mMenu.load();//This needs to be after spritesheet.loadalltextures
//		Font.load(gl);//This needs to be after spritesheet.loadalltextures
		
//		gl.glEnable(GL10.GL_CULL_FACE);				// Culling
//		gl.glCullFace(GL10.GL_BACK);

		gl.glEnable(GL10.GL_TEXTURE_2D);			// Mapping
		gl.glShadeModel(GL10.GL_SMOOTH);			// Smooth Shading
		gl.glClearColor(1.0f, 1.0f, 1.0f, .5f);		// Color BG
		gl.glClearDepthf(1.0f);						// Depth Buffer Setup
		gl.glEnable(GL10.GL_DEPTH_TEST);			// Depth Testing
		gl.glDepthFunc(GL10.GL_LEQUAL);				// Type of Depth Test

		// For Transparency
		gl.glEnable(GL10.GL_BLEND);
		gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

		// Perspective Calculations
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
	}

	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		// Viewport operations go here.		
    	gl.glViewport(0, 0, width, height); 	//Reset The Current Viewport
		gl.glMatrixMode(GL10.GL_PROJECTION); 	//Select The Projection Matrix
		gl.glLoadIdentity(); 					//Reset The Projection Matrix

		GLU.gluPerspective(gl, Camera.FOVY, Camera.SCREEN_RATIO, 0.1f, 100.0f);

		gl.glMatrixMode(GL10.GL_MODELVIEW); 	//Select The Modelview Matrix
		gl.glLoadIdentity(); 					//Reset The Modelview Matrix
	}

	@Override
	public void onDrawFrame(GL10 gl) {
		if(mLastTime == 0){
			mLastTime = mClock.getTime();
			
			//TODO:  keep a dirty bool
			//       if screen nothing on the screen has changed since mLastTime
			//       do not clear, and do not redraw!
		}
		
		// Clears stuff
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		gl.glColor4f(1, 1, 1, 1);
		// Restores Identity
		gl.glLoadIdentity();

		if(mLoadGameResources == 0){
			LoadingScreen.getInstance().draw(gl);
			mLoadGameResources++;
			return;
		}
		
		if(mLoadGameResources == 1){
			mLoadGameResources = 2;
	    	long time = System.nanoTime();
  	
			SpriteSheet.getInstance().loadAllTextures(gl);  
			AnimationSheet.getInstance().loadAllTextures(gl);
			SoundManager.getInstance().LoadResources(mActivity);
			AnimationManager.getInstance().initializeManager();
			
	    	long elapse = System.nanoTime() - time;
			Logger.popUp("Loading resources took: " + elapse/1000000);
			//Don't really need to do this, will be necessary if/when loading screen is animated
			LoadingScreen.getInstance().hide();
		}
		
		AnimationManager.getInstance().tick(mClock.getTime());
		
		if(!mGame.hasStarted()){
			mMenu.draw(gl);
		}
		else{
			mGame.tick();
			if(mCamera.getFocusedObject() != null){ mCamera.center(mCamera.getFocusedObject().getLocation()); }
			
			gl.glScalef(mCamera.getScale(), mCamera.getScale(), 1);
			gl.glTranslatef(-mCamera.getLeft()-Camera.GL_WIDTH/2, -mCamera.getBottom()-Camera.GL_HEIGHT/2,  Camera.Z_DISTANCE);
			mGame.draw(gl);
		}	
	}
	public static boolean renderStarted(){ return mLastTime > 0; }//Check for draw start
	public void loadGameResources(){ mLoadGameResources = mLoadGameResources < 0 ? 0 : 2; }
}
